package bupt.xixi.codec;

import bupt.xixi.entity.RpcRequest;
import bupt.xixi.enumeration.Codec;
import bupt.xixi.enumeration.PackageType;
import bupt.xixi.serializer.ICommonSerializer;
import bupt.xixi.serializer.SerializerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * +---------------+---------------+-----------------+-------------+
 * |  Magic Number |  Package Type | Serializer Type | Data Length |
 * |    4 bytes    |    4 bytes    |     4 bytes     |   4 bytes   |
 * +---------------+---------------+-----------------+-------------+
 * |                          Data Bytes                           |
 * |                   Length: ${Data Length}                      |
 * +---------------------------------------------------------------+
 */
public class CommonEncoder extends MessageToByteEncoder {

    private static final Logger logger = LoggerFactory.getLogger(CommonEncoder.class);


    private final ICommonSerializer serializer;

    public CommonEncoder(Codec.SerializeType type) {
        // 初始化时候设置好serializer用的是哪种，这里只实现了默认的Kryo
        this.serializer = SerializerFactory.getByCode(type.getCode());
    }


    @Override
    protected void encode(ChannelHandlerContext context, Object message, ByteBuf byteBuf) throws Exception {
        // 1. 写入MagicNumber魔数
        byteBuf.writeInt(Codec.MAGIC_NUMBER);
        // 2. 写入PackageType包种类
        if (message instanceof RpcRequest) {
            byteBuf.writeInt(PackageType.REQUEST_PACK.getCode());
        } else {
            byteBuf.writeInt(PackageType.RESPONSE_PACK.getCode());
        }
        // 3. 写入序列化器的种类
        byteBuf.writeInt(serializer.getCode());
        // 4. 得到编码后的字节
        byte[] bytes = serializer.serialize(message);
        // 5. 写入序列化后的字节长度
        byteBuf.writeInt(bytes.length);
        // 6. 写入数据
        byteBuf.writeBytes(bytes);
    }
}
